package com.usian.common.exception;
import com.google.common.collect.ImmutableMap;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 公共异常处理的类
 */
@ControllerAdvice//控制器增强
@Log4j2
public class ExceptionCatch {

    //使用EXCEPTIONS存放异常类型和错误代码的映射，ImmutableMap的特点的一旦创建不可改变，并且线程安全
    private static ImmutableMap<Class<? extends Throwable>, ResponseResult> EXCEPTIONS;
    //使用builder来构建一个异常类型和错误代码的异常
    protected static ImmutableMap.Builder<Class<? extends Throwable>,ResponseResult> builder = ImmutableMap.builder();


    //异常处理器 与上面注解一起使用，可以拦截指定的异常信息
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ResponseResult exception(Exception exception) {
        //记录日志
        System.out.println(exception.getMessage());
        if(EXCEPTIONS == null)
            EXCEPTIONS = builder.build(); //构建初始化
        final ResponseResult result = EXCEPTIONS.get(exception.getClass());
        if (result != null) {
            //如果匹配了异常  直接返回对应异常提示
            return result;
        } else {
            // 代表异常没有，返回统一异常码（不可预知，超出范围的异常）
            return ResponseResult.errorResult(99999,"出现未知异常");
        }
    }
//定义一个静态方法，来处理一些我们可预见的基础异常（空指针、下标越界等）
    static{
        //在这里加入一些基础的异常类型判断
        builder.put(HttpMessageNotReadableException.class,ResponseResult.errorResult( 1,"非法参数"));
        builder.put(NullPointerException.class,ResponseResult.errorResult(1,"出现空对象异常"));
        builder.put(IndexOutOfBoundsException.class,ResponseResult.errorResult(1,"下角标越界异常"));
        //自己填充的，zero异常
        builder.put(ArithmeticException.class,ResponseResult.errorResult(1,"除数不能为0"));
    }
}
